package io.shuttle.mbe.api

import io.shuttle.mbe.api.types.NumOrNumArr
import io.shuttle.mbe.api.types.Value1Function
import io.shuttle.mbe.api.types.Value3Function
import io.shuttle.mbe.core.Promise

interface Process {
    // Returns the ID of the renderer process for the specified tab.
    // @return Process ID of the tab's renderer process.
    fun getProcessIdForTab(
        // The ID of the tab for which the renderer process ID is to be returned.
        tabId: Number,
        callback: Value1Function<Number>? = null
    ): Promise<Number>

    // Retrieves the process information for each process ID specified.
    // @return A dictionary of Process objects for each requested process that is a live child process of the current browser process, indexed by process ID. Metrics requiring aggregation over time will not be populated in each Process object.
    fun getProcessInfo(
        // The list of process IDs or single process ID for which to return the process information.
        // An empty list indicates all processes are requested.
        processIds: NumOrNumArr,
        // True if detailed memory usage is required.
        // Note, collecting memory usage information incurs extra CPU usage and should only be queried for when needed.
        includeMemory: Boolean,
        callback: Value1Function<Any>? = null
    ): Promise<Any>

    // Terminates the specified renderer process. Equivalent to visiting about:crash, but without changing the tab's URL.
    // @return True if terminating the process was successful, and false otherwise.
    fun terminate(
        // The ID of the process to be terminated.
        processId: Number,
        callback: Value1Function<Boolean>? = null
    ): Promise<Boolean>

    // Fired each time a process is created, providing the corrseponding Process object.
    val onCreated: Events.Event<Value1Function<Process>>

    // Fired each time a process is terminated, providing the type of exit.
    // @callback (processId: number, exitType: number, exitCode: number) => void
    val onExited: Events.Event<Value3Function<Number, Number, Number>>

    // Fired each time a process becomes unresponsive, providing the corrseponding Process object.
    val onUnresponsive: Events.Event<Value1Function<Process>>

    // Fired each time the Task Manager updates its process statistics, providing the dictionary of updated Process objects, indexed by process ID.
    val onUpdated: Events.Event<Value1Function<Any>>

    // Fired each time the Task Manager updates its process statistics, providing the dictionary of updated Process objects, indexed by process ID. Identical to onUpdate, with the addition of memory usage details included in each Process object. Note, collecting memory usage information incurs extra CPU usage and should only be listened for when needed.
    val onUpdatedWithMemory: Events.Event<Value1Function<Any>>

    data class Cache(
        // The part of the cache that is utilized, in bytes.
        var liveSize: Number,
        // The size of the cache, in bytes.
        var size: Number,
    )

    data class Process(
        // The most recent measurement of the process's CPU usage, expressed as the percentage of a single CPU core used in total,
        // by all of the process's threads. This gives a value from zero to CpuInfo.numOfProcessors*100,
        // which can exceed 100% in multi-threaded processes.
        // Only available when receiving the object as part of a callback from onUpdated or onUpdatedWithMemory.
        var cpu: Number?,
        // he most recent information about the CSS cache for the process.
        // Only available when receiving the object as part of a callback from onUpdated or onUpdatedWithMemory.
        var cssCache: Cache?,
        // Unique ID of the process provided by the browser.
        var id: Number,
        // The most recent information about the image cache for the process.
        // Only available when receiving the object as part of a callback from onUpdated or onUpdatedWithMemory.
        var imageCache: Cache?,
        // The most recent measurement of the process JavaScript allocated memory, in bytes.
        // Only available when receiving the object as part of a callback from onUpdated or onUpdatedWithMemory.
        var jsMemoryAllocated: Number?,
        // The most recent measurement of the process JavaScript memory used, in bytes.
        // Only available when receiving the object as part of a callback from onUpdated or onUpdatedWithMemory.
        var jsMemoryUsed: Number?,
        // The debugging port for Native Client processes.
        // Zero for other process types and for NaCl processes that do not have debugging enabled.
        var naclDebugPort: Number?,
        // The most recent measurement of the process network usage, in bytes per second.
        // Only available when receiving the object as part of a callback from onUpdated or onUpdatedWithMemory.
        var network: Number?,
        // The ID of the process, as provided by the OS.
        var osProcessId: Number?,
        // The most recent measurement of the process private memory usage, in bytes.
        // Only available when receiving the object as part of a callback from onUpdatedWithMemory or getProcessInfo with the includeMemory flag.
        var privateMemory: Number?,
        // The profile which the process is associated with.
        var profile: String,
        // The most recent information about the script cache for the process.
        // Only available when receiving the object as part of a callback from onUpdated or onUpdatedWithMemory.
        var scriptCache: Cache?,
        // The most recent measurement of the process's SQLite memory usage, in bytes.
        // Only available when receiving the object as part of a callback from onUpdated or onUpdatedWithMemory.
        var sqliteMemory: Number?,
        // Array of TaskInfos representing the tasks running on this process.
        var tasks: List<TaskInfo>,
        // The type of process.
        var type: ProcessType,
    )

    enum class ProcessType {
        browser,
        renderer,
        extension,
        notification,
        plugin,
        worker,

        // Obsolete, will never be returned.
        nacl,

        // Obsolete, will never be returned.
        service_worker,
        utility,
        gpu,
        other
    }

    data class TaskInfo(
        // Optional tab ID, if this task represents a tab running on a renderer process.
        var tabId: Number?,
        // The title of the task.
        var title: String,
    )
}